#pragma  once
#include <stdint.h>
#include <list>
#include "base/net/i_session.h"
#include "Common/NetPack/NetPack.h"
#include "base/core/lua_head.h"
#include "base/core/point3.h"
#include "base/core/log.h"
#include "base/core/double_list.h"
#include "Common/Utility/ServerTime.h"
#include "Common/TaskBalance/TaskNode.h"
#include "Scene/SceneMgr.h"
#include "ProtoBuffer/AllProtocol.h"

#include "Character/buff/BuffEffectCfg.h"
#include "Common/Event/Event.h"
#include "Common/Timer/TimerAxis.h"
#include "base/core/CTArrayList.hpp"
#include "Common/LogDefine.h"

#ifdef _MSC_VER
#pragma warning(disable:4267) //conversion from 'size_t' to 'int', possible loss of data
#pragma warning(disable:4100) //未引用的形参
#endif

//#define AI_DEBUG 1
//#define AI_MONSTER_VS_MONSTER 1

class CreatureCommonAI;
class Scene;
class Grid;
class Part;

enum PkMode
{
	PK_MODE_NONE = 0, //no pk mode
	PK_MODE_CAMP = 1, //阵营模式
	PK_MODE_COMMON = 2, //公会模式
	PK_MODE_KILLER = 3, //杀谬模式
	PK_MODE_GOOD_EVIL = 4, //善恶模式
	PK_MODE_COUNT,
};

enum PkKillingValue
{
	PK_WANTED_RED_LINE = 1, //PK杀谬值被通缉红线
};

//杀谬植
enum PkKillingLevel
{
	PK_KILLING_LEVEL_ONE = 1,	//好勇斗狠
	PK_KILLING_LEVEL_TWO = 2,	//红名PK植
	PK_KILLING_LEVEL_THREE = 3,	//心狠手辣
	PK_KILLING_LEVEL_FOUR = 4,	//杀人如麻
	PK_KILLING_LEVEL_FIVE = 5,	//凶神恶煞
};

enum CreatureBuffStateIndex
{
	CREATURE_BUFF_STATE_DIZZY = 0,			// 晕眩
	CREATURE_BUFF_STATE_FROZEN = 1,			//冰冻 缠绕
	CREATURE_BUFF_STATE_WINDING = 2,		//缠绕
	CREATURE_BUFF_STATE_HP_SHIELD = 3,			// 加血护盾
	CREATURE_BUFF_STATE_INVISIBLE = 4, //隐身
	CREATURE_BUFF_STATE_SEEINVISIBLE = 5, //反隐身
	CREATURE_BUFF_STATE_NOSEE = 6, //致盲
	CREATURE_BUFF_STATE_MABI = 7, //麻痹
	CREATURE_BUFF_STATE_WUDI = 8, //无敌
	CREATURE_BUFF_STATE_REFIX_SKILL = 9, //修改技能
	CREATURE_BUFF_STATE_ADD_EXTRA_DAMAGE = 10, //
	CREATURE_BUFF_STATE_REDUCE_EXTRA_DAMAGE = 11, //
	CREATURE_BUFF_STATE_CANNOT_USE_SKILL = 12, //不能使用技能
	CREATURE_BUFF_STATE_CHAOFENG = 13, //嘲讽
	CREATURE_BUFF_DISMOUNT = 14, //下坐骑或禁止召唤坐骑
	MAX_INDEX,
};

class CreatureBuffState
{
public:
	CreatureBuffState() { m_state.resize(MAX_INDEX); }
	virtual ~CreatureBuffState() { m_state.clear(); }
public:
	uint32_t GetValue(CreatureBuffStateIndex state) const
	{
		if (state >= m_state.size() || state < 0)
		{
			return 0;
		}
		return m_state[state];
	}

	bool	GetState(CreatureBuffStateIndex state) const
	{
		if (state >= m_state.size() || state < 0)
		{
			return false;
		}
		return m_state[state] > 0;
	}

	void	AddState(CreatureBuffStateIndex state)
	{
		if (state >= m_state.size() || state < 0)
		{
			return;
		}
		m_state[state]++;
	}

	void RemoveState(CreatureBuffStateIndex state)
	{
		if (state >= m_state.size() || state < 0)
		{
			return;
		}
		if (m_state[state] > 0)
		{
			m_state[state]--;
		}
		else
		{
			m_state[state] = 0;
		}
	}
public:
	std::vector<uint8_t>	m_state;
};

struct ViewData
{
	ViewData()
	{
		//cid = 0;
		pCreature = nullptr;
		nMeInHisVisionPos = -1;
	}
	//CharIDType cid;
	Creature* pCreature;
	short nMeInHisVisionPos;
};

struct DoubleListViewData
{
	DoubleListViewData()
	{
		//cid = 0;
		pCreature = nullptr;
		nMeInHisVisionPos = nullptr;
	}

	~DoubleListViewData()
	{
		//cid = 0;
		pCreature = nullptr;
		nMeInHisVisionPos = nullptr;
	}
	//CharIDType cid;
	Creature* pCreature;
	DoubleNode* nMeInHisVisionPos;
};

enum VisionUnitType
{
	VISIONTYPE_NONE = 0,					/*无				is_role_vision_sull 80 vision*/
	VISIONTYPE_ALREADY_IN_VISION,		/*已经在视野里		无需判断视野*/
	VISIONTYPE_NEAR,						/*近距离视野关系  is_role_near_vision_full 100 vision*/
	VISIONTYPE_SPEC_RELATIONSHIP,		/*特殊社交关系视野类型 is_role_vision_mem_full 512 vision*/
	VISIONTYPE_VENDOR,					/*摆摊视野单元			is_role_vison_mem_full 512 vision*/
};

enum
{
	NINE_VISION_NONE = 0,
	NINE_VISION_SPECIAL_RELATIONSHIP = 1, //存放有关系的玩家
	NINE_VISION_THE_NEAR_GRID = 2,	//没有关系的玩家
	NINE_VISION_MAX,
};

enum
{
	NEW_SEE_VISION_NONE = 0, //CTArrayList里的0号链表是Free List， 不能使用
	NEW_SEE_VISION_SPECIAL_RELATIONSHIP = 1,
	NEW_SEE_VISION_LESS_HALF_OF_HALF_MAX_SIGHT_RANGE = 2,
	NEW_SEE_VISION_LESS_HALF_OF_MAX_SIGHT_RANGE = 3,
	NEW_SEE_VISION_THAN_HALF_OF_MAX_SIGHT_RANGE = 4,
	NEW_SEE_VISION_MAX,
};

enum
{
	SEE_VISION_NONE = 0, //CTArrayList里的0号链表是Free List， 不能使用
	SEE_VISION_SPECIAL_RELATIONSHIP = 1,
	SEE_VISION_IN_THE_SIGHT_RANGE = 2,
	SEE_VISION_MAX,
};

#define MAX_SEE_CREATURE_COUNT_IN_THE_VISION 200

//生物关系值
enum
{
	PLAYER_NONE = 0, //中立玩家，新玩家，没有选择阵营玩家
	MONSTER_NONE = 1, //中立怪物
	REBOT_NONE = 2, //机器人
	CREATURE_NO_BE_ATTACK = 3, //不可被攻击的生物, 包过（中立NPC, 特殊怪物,矿物）
	PLAYER_CAMP_LIGHT = 4, //光明阵营玩家
	MONSTER_CAMP_LIGHT = 5, //光明阵营怪物
	NPC_CAMP_LIGHT = 6,//光明阵营NPC
	PLAYER_CAMP_DARK = 7, //黑暗阵营玩家
	MONSTER_CAMP_DARK = 8, //黑暗阵营怪物
	NPC_CAMP_DARK = 9,	//黑暗阵营NPC
	MONSTER_TA = 10, //怪物塔
	MONSTER_CAN_BE_DESTROYED = 11, //可破坏物件
	MONSTER_TRIGGER_ALL = 12, //all可触发物件
	MONSTER_TRIGGER_PLAYER = 13,//player可触发物件
	MONSTER_TRIGGER_MONSTER = 14,//monster可触发物件
	MONSTER_TRIGGER_NPC = 15,//npc可触发物件
	MONSTER_NONE_TRAP = 16, //中立陷阱
	MONSTER_CAMP_LIGHT_TRAP = 17, //光明陷阱
	MONSTER_CAMP_DARK_TRAP = 18, //黑暗陷阱
	MONSTER_NONE_USE_THING = 19, //中立可使用怪
	MONSTER_CAMP_LIGHT_USE_THING = 20, //光明可使用怪
	MONSTER_CAMP_DARK_USE_THING = 21, //黑暗可使用怪
	FIREND_SHIP_MAX,
};

int gGetCreatureFriendShip(Creature* pCreature);

bool gGetCreatureVsCreature(int first, int second);

class CreatureVisionData
{
public:
	CreatureVisionData();

	virtual ~CreatureVisionData();

public:
	DoubleNode* AddPVPSeeList(int list, Creature* pCreature);
	DoubleNode* AddPVMSeeList(Creature* pCreature);
	bool DelPVMSeeList(DoubleNode* node);
	bool DelPVPSeeList(DoubleNode* node);

//	int AddPVPSeeListFront(int list, Creature* pCreature)
//	{
//		if (list <= 0 || list >= SEE_VISION_MAX)
//		{
//			return -1;
//		}
//		ViewData data;
//		//data.cid = cid;
//		data.pCreature = pCreature;
//		return m_seeLst.AddItemFront(list, data);
//	}
public:
	DoubleList	m_doublePVPSeeLst;	//人和人的视野处理
	DoubleList	m_doublePVMSeeLst; //这里只处理人和其他非人生物之间的视野管理， 怪物或NPC必须所有人都能看到
	char	chVisionUnitType;			//用于记录此角色视野单元在进入别人视野处理的标记
};

class Creature : public ITask, public  IEventExecuteSink, public ITimerHandler
{
protected:
	typedef std::list<CharIDType>				     Uint64Lst;
	typedef Uint64Lst::iterator          		    Uint64Iter;

	typedef std::vector<CharIDType>					Uint64Vec;
	typedef std::vector<CharIDType>::iterator			Uint64VecIter;

	typedef std::unordered_map<uint32_t, uint32_t>	Uint32Map;
	typedef std::unordered_map<uint32_t, uint64_t>	Uint64Map;

	Point3<float> m_pos;                   //当前生物坐标
	uint32_t m_sceneId;                    //生物所在场景实例id
	uint32_t m_mapId;                      //地图模板id
	CharIDType m_Cid;						   //生物实例id

	CreatureVisionData m_visionData;		//

	float	 m_sightRange;                 //可见视野范围长度
	uint8_t m_creatureKind;               //实体类型
	uint32_t m_seeInterval;                //视野更新间隔(毫秒)
	uint64_t m_lastSeeTime;                //上次更新视野时间
	uint64_t m_lastUpdateNineTime;			//上次更新9宫格时间

	//float m_fspeed;                        //移动速度
	uint32_t m_fRevertHpTime;				   //回复血，蓝百分比 单位毫秒

	Grid  *m_pMyGrid;                         //生物在地图中的格子
	DoubleNode*	m_gridNode;							//生物在地图中的格子链表中的节点
	Scene *m_pScene;                       //生物所在场景的对象
	Point2<uint32_t> m_littleGrid;

	uint32_t m_curstate;                     //生物当前状态

	SynAttrsAllClient m_attrBroadcastClient; //广播

	Uint32Map  m_attrsCache;                //单个客户端同步属性缓存
	Uint64Map  m_attrs64Cache;				//单个客户端同步64位属性缓存
	Uint32Map  m_attrsBroadCastCache;       //广播同步属性缓存
	Uint64Map  m_attrs64BroadCastCache;		//广播64位属性缓存
	Point3<float> m_dir; //运动方向,单位向量
	bool	   m_destory;	//是否要回收
	bool	   m_bCanBeSeen;	//是否被见
	uint64_t   m_planeID;		//位面ID
	bool	   m_bAttack;		//是否能被攻击，主要是处理传送后，不移动，不让攻击
	bool	   m_willDead;		//将死状态
public:
	Creature();
	virtual ~Creature();

	virtual bool Init();
	virtual bool UnInit();
	virtual void Update(uint64_t tick);
	virtual bool CheckAttrValue(uint32_t CANum, uint32_t attrValue){ return true; };
	virtual bool AddAttr(uint32_t CANum, int64_t attrValue, bool syn, uint64_t relationCid = 0) = 0;
	virtual bool AddAttrCache(uint32_t CANum, int64_t attrValue, uint64_t relationCid = 0) = 0;
	virtual void SetAttr(uint32_t CANum, int64_t attrValue, bool syn = false) = 0;
	virtual void SetAttrCache(uint32_t CANum, int64_t attrValue) = 0;
	virtual void SetAttrPA(uint32_t PANum, int64_t attrValue, bool syn = false, bool isCalc = true){};
	virtual void LogBase(LogTid logid, JsonObject &obj){}

	virtual void OnDead(uint64_t killerCid);
	virtual void OnCorpse(); //尸体停留阶段
	virtual void OnRevive(uint64_t saverCid);
	virtual void FindCreatureInScene(Uint64Lst& clist);
	virtual void FindSeeListInNineGride(Creature* pSrc, std::vector<Creature*>* clist, Point3<float>& sorPos);
	virtual void FindDoubleSeeListInNineGride(Creature* pSrc, std::vector<Creature*>& clist, Point3<float>& sorPos);
	virtual void OnExecute(uint16_t nEventID, uint64_t nSrcID, uint8_t bySrcType, void *pContext, int32_t nLen) {};
	virtual void OnTimer(uint32_t nTimerID) {};
	virtual bool IsDestory() { return m_destory; }
	virtual void SetDestory() { m_destory = true; }
	virtual AccountGameState GetAccountState(){ return ACCOUNT_GAME_STATE_NULL; }
	virtual bool IsDead(){ return m_curstate >= State_dead; }
	virtual int64_t GetAttr(uint32_t attrNum) { return 0; };
	virtual int64_t GetPAttrValue(uint32_t attrPANum){ return 0; };
	virtual uint32_t GetAttrNum(uint32_t CommonAttrNum) = 0;
	virtual uint32_t GetConfigId(){ return 0; } //获取生物对应实例配置表Id
	virtual int32_t GetPosIdx() { return -1; } //获取出生坐标所在列表的索引，暂时只用于收集
	void SetPos(Point3<float>& pos);
	inline Point3<float>& GetPos() { return m_pos; }
	void SetDir(const Point3<float>& point);
	inline Point3<float>& GetDir() { return m_dir; }
	inline Grid* GetGrid() { return m_pMyGrid; }
	inline DoubleNode* GetGridNode() { return m_gridNode; }
	inline void SetGrid(Grid* pGrid) { m_pMyGrid = pGrid; }
	inline void SetGridNode(DoubleNode* pNode) { m_gridNode = pNode; }
	inline Scene* GetScene() { return m_pScene; };
	inline uint32_t GetSceneId() const { return m_sceneId; };
	inline uint32_t GetMapId() const { return m_mapId; }
	inline void     SetMapId(uint32_t mapId){ m_mapId = mapId; }
	virtual uint8_t CreatureKind() const { return m_creatureKind; };
	inline CharIDType GetCid() const { return m_Cid; }
	float  GetSpeed() ;
	void   SetSpeed(float f,bool isSync=false);
	inline float GetSightRange() const { return m_sightRange; }
	virtual uint32_t GetUid() { return  0; }
	virtual uint32_t GetClientId() { return 0; }
	virtual void GetGateClientId(uint32_t& gateId, uint32_t& clientId){};
	virtual bool IsWillDead() const { return m_willDead; }
	virtual void SetWillDead(bool will) { m_willDead = will; }

	//需要确定来源的属性，都调这个接口
	virtual void AddSourceAttr(uint32_t CANum, int64_t value,bool sync, ItemOrCurrencySource sourType);

	//视野类接口
	virtual void UpdateSeeLst();
	virtual void UpdateNineGridLst();
	virtual void GetVisibleDataToClient(CreaturesCreateData& cvData) = 0;  //获取客户端可见数据
	virtual bool GetRockeMoveDataToClient(ActorRockerMove &rockmove){ return false; }
	virtual bool GetMouseMoveDataToClient(ActorMove &rockmove){ return false; }
	virtual void GetMoveDataToClient(ActorMove &mouseMove, ActorRockerMove &rockmove){};
	virtual void AddSeeNewCreature(Creature* pCreature) { }
	//用于重连上后，再重新发送一次全体视野信息。
	void SendAllSeeCreatureListToClient();

	//将对方加入到自己的视野中
	virtual void SimpleAddPVPSeeLst(int releation, Creature* pOther);
	virtual void SimplePVMAddSeeLst(Creature* pOther);
	virtual void ReplacePVPSeeList(int releation, Creature* pOther, std::vector<Creature*>& vecBeen);
	virtual void AddPVPSeeLst(int releation, Creature* pOther, std::vector<Creature*>& vecBeen);
	virtual void AddPVMSeeLst(Creature* pOther, std::vector<Creature*>& vecBeen);
	virtual DoubleNode* DelPVMSeeLst(DoubleNode* delpos, Creature* pOther);
	virtual DoubleNode* DelPVPSeeLst(DoubleNode* delpos, Creature* pOther);
	//视野裁剪接口 后面需要做更复杂的视野裁剪那么子类继承去实现
	virtual bool ViewFliter(Creature* pCreature, float dict);

	virtual std::vector<CharIDType> GetSeeLst();
	virtual void GetSeeLst(std::vector<CharIDType>& );
	std::vector<Creature*> GetCreatureList();

	virtual CreatureVisionData& GetVisionData() { return m_visionData; }
	virtual const CreatureVisionData& GetVisionData() const { return m_visionData; }

	//获取怪物模型半径, 长度单位m
	virtual float GetModelRadius(){ return 0; };

	//void NoticeUpdateSeeCreature(CharIDType cid);

	//void NoticeNineGridCreatureUpdateSeeList();
	void NoticeNineGridLeave();
	void SendNoticeCreateOneCreature(Creature * pOther);
	void SendNoticeDestoryOneCreature(Creature * pOther);
	//******************调用部件接口******************
	//scenceId:目标场景ID（唯一ID，静态地图场景ID和地图ID相同），dstPos：目标场景坐标，mapId：地图ID,transParam:传送参数
	virtual bool TransScene(uint32_t scenceId, Point3<float>& dstPos, uint32_t mapId, STransParam &transParam); //强制传送(场景内传送、切场景传送)
	//进入场景(这个接口只给移动部件和生物内部自身调用，其他请调用transScene)
	virtual bool EnterScene(uint32_t sceneId, Point3<float>& enterPos, STransParam &transParam);

	//离开场景
	virtual bool LeaveScene();

	//瞬间移动
	virtual bool Teleporting(Point3<float> dstPos) { return true; }
	//被击退
	virtual bool BeatBack(Point3<float> dstPos) { return true; }

	//向目标点移动 主要AI用
	virtual bool MoveTo(Point3<float> dstPos) { return true; }
	//停止当前移动
	virtual void StopMove(bool isBroadClent = true)	 { }							//停止当前移动,广播告诉其他人

	//给生物加状态包
	//pTarget为空:给自己加状态包
	//pClientStatebag-   NULL: 表明状态buff信息 buff部件自己同步  非NULL:状态buff挂到其他模块一起同步
	//virtual bool AddStateBag(uint32_t skillid, uint32_t lev, ProtoBuf::BuffBagDetailInfo* pClientStatebag, Creature* pTarget = nullptr) { return true; }

	//获取对应部件指针,part dynamic外部对应转一下
	virtual Part* GetPart(uint32_t partType) { return NULL; }

	//****************消息发送接口*****************
	//数据广播、同步(playerId必须是玩家id, moudleId各个模块的id,发送给上层逻辑系统)
	bool BroadCastData(uint16_t module, uint16_t cmd, ProtoBufBase* buf, bool IncludeMyself = false);
	bool BroadCastData(uint16_t cmd, ProtoBufBase* buf, bool IncludeMyself = false);

	bool SendDataToClient(uint16_t module, uint16_t cmd, ProtoBufBase* buf);
	bool SendDataToClient(uint16_t cmd, ProtoBufBase* buf);
	bool SendDataToClientEx(uint16_t module, uint16_t cmd, ProtoBufBase* buf);

	//发送往中心服
	virtual void SynAttrToClient();

	// 分帧任务处理函数
	bool DoTask(TaskNodeId type, void* data, uint32_t size);


	//判断是否能发送消息
	bool IsCanSendMessage();

	//设置成员
	void SetCanBeSeenFlag(bool isCanBeSeen);
	void SetPlaneID(uint64_t planeID);
	bool GetCanBeSeenFlag();
	void SetBeAttackFlag(bool bFlag);
	bool GetBeAttackFlag();
	uint64_t GetPlaneID();

	////////////////////////////////////////////////////////////////////////////////
	// lua class
	// lua 注册函数不支持有64位和枚举类型的的函数注册，需要重新包装为支持的类型
	// 返回值为bool类型的函数一律重新封装为返回值为int类型的lua函数
public:
	bool HasBuffState(CreatureBuffStateIndex state) const;
	void AddBuffState(CreatureBuffStateIndex state);
	void RemoveBuffState(CreatureBuffStateIndex state);

	bool HasBuffStateNoMove() const; //因为中了特殊的buff，不能移动,比如眩晕，冰冻
	bool HasBuffStateNoSkill() const; //因为中了特殊的buff，不能使用技能shi
	bool HasBuffStateReduceDamage() const; //因为中了特殊的buff，比如生命盾,可以在不加属性的情况下，影响对玩家的伤害
	bool HasBuffStateAddExtraDamage() const;
	bool HasBuffStateRefixSkill() const;
public:
	//PVP 相关
	virtual bool IsFriendSide(Creature* pCreature) { return false; }
	//特殊关系 比如 队友， 师徒， 情侣， 夫妻， 密友
	virtual bool IsSpecialRelationShip(Creature* pCreature) { return false; }
	//是否能被打区域
	virtual bool IsCanBeAttackByCurrentPos();
public:
	virtual void AddSummon(CharIDType summonCid);
	virtual void DelSummon(CharIDType summonCid);
	virtual std::vector<Monster*> GetSummons();
	virtual bool IsExistSummon();
	virtual void UpdateSummon();
	virtual void AddSummonHateCid(CharIDType targetCid);
public:
	//判断生物身上是否有buff state bag
	virtual bool HasBuffStateBag(uint32_t stateBagId) { return false; }
	virtual void BuffEffect_ReduceDamage(Creature* pAttack, uint32_t skillId, int32_t &damage) { }
	virtual void BuffEffect_AddExtraDamage(Creature* pBeAttacked, uint32_t skillId, int32_t &damage) { }
	virtual void BuffEffect_CleanupAllFadeOutEffects(BuffInfoEndType endType);
public:
	bool HasBuffStateNoAiControl() const; //因为中了特殊的buff，怪物AI暂时不能用
	virtual void UpdateAiInfo(uint64_t deltaTime);
	virtual bool BeenSeeByPlayer();
	CreatureCommonAI*	GetAiData() const { return m_aiData; }
public:
	virtual bool CanTrans(ERetCode &ret, uint32_t dstSceneId, uint32_t dstMapId) { return true; }
protected:
	CreatureBuffState		m_buffState;
	CreatureCommonAI*		m_aiData;
protected:
	std::list<CharIDType> m_summons;
public:
	static bool RegistLuaClass(lua_State* state);
	int	LuaIsDead();

	// 执行技能相关的 lua string
	int DoSkillString(uint32_t skillId, uint32_t skillLevel, const char* luaString, CharIDType casterId, CharIDType targetId, uint32_t chargeTime = 0);

	//将附加伤害等字符串解析为公式 + 参数格式,传入伤害次数,暂时放这，可以放到字符串公共方法中
	//bool GetFormula(string str, VEC_INT32 &vOutParam)  const;
};
